<?php

/** 
 * @Author: 李红雨 - RainLee <rainlee1990@yeah.net>
 * @Date: 2022-06-21 14:12:08
 * @LastEditors: 李红雨 - RainLee <rainlee1990@yeah.net>
 * @LastEditTime: 2022-06-21 15:53:23
 * @Description: File Description
 */

namespace rainlee\authn;

use InvalidArgumentException;
use think\App;
use think\helper\Str;

class AuthnManager
{

    protected $app;

    protected $guards = [];

    public function __construct(App $app)
    {
        $this->app = $app;
    }

    /**
     * 获取看守器类
     * 
     * @param  string|null  $name
     * @return 
     */
    public function guard($name = null)
    {

        $name = $name ?: $this->getDefaultGuard();
        if (is_null($name)) {
            throw new InvalidArgumentException(sprintf(
                'Unable to resolve NULL guard for [%s].',
                static::class
            ));
        }
        return $this->guards[$name] ?? $this->guards[$name] = $this->resolve($name);
    }

    /**
     * 创建看守器
     *
     * @param string $name
     * @return mixed
     *
     */
    protected function resolve(string $name)
    {
        $config = $this->resolveConfig($name);

        if (is_null($config)) {
            throw new InvalidArgumentException("Auth guard [{$name}] is not defined.");
        }

        $method = 'create' . Str::studly($config['driver']) . 'Driver';
        if (method_exists($this, $method)) {
            return $this->$method($name, $config);
        }

        throw new InvalidArgumentException("Auth guard driver [{$name}] is not defined.");
    }

    /**
     * 解析配置
     * 
     * @param  string  $name
     * @return array|null
     */
    protected function resolveConfig($name)
    {
        return $this->app->config->get('authn.guards.' . $name);
    }

    /**
     * 创建基于SESSION的认证看守器
     *
     * @param  string  $name
     * @param  array  $config
     * @return \rainlee\authn\guard\SessionGuard
     */
    protected function createSessionDriver($name, $config)
    {
        return new \rainlee\authn\guard\SessionGuard($name, $config);
    }

    /**
     * 创建基于JWT的认证看守器
     *
     * @param  string  $name
     * @param  array  $config
     * @return \rainlee\authn\guard\JwtGuard
     */
    protected function createJwtDriver($name, $config)
    {
        return new \rainlee\authn\guard\JwtGuard($name, $config);
    }

    /**
     * 获取默认看守器
     * 
     * @return string|null
     */
    public function getDefaultGuard()
    {
        return $this->app->config->get('authn.default');
    }

    /**
     * 动态调用
     * @param string $method
     * @param array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->guard()->$method(...$parameters);
    }
}
